#include <unistd.h>
#include "../logs/log.h"
#include <chrono>
#include <cstdio>

using namespace define_log;

// 测试三要素
// 测试环境
// 测试项目,方法
// 测试结果

// 测试项目：1. 同步：单线程， 多线程； 2. 异步：单线程，多线程

// 创建一个接口，接口参数提供：测试日志器名字，线程数量，日志数量，日志大小
void thr_bench(size_t thr_num, size_t msg_num, size_t log_size)
{
    std::cout << " 多线程" << std::endl;
    // 创建多线程，并让线程完成各自日志输出任务
    std::vector<std::thread> _threads;
    size_t time = msg_num / thr_num;
    double max_during = 0;
    std::string log_msg(log_size, 'c');
    for (int i = 0; i < thr_num; i++)
    {
        _threads.emplace_back(std::thread([&, i]
                                          {
        //在日志开始打印日志前，进行计时，获取打印时间
        auto start = std::chrono::high_resolution_clock::now();
        for (int n = 0; n < time; n++)
            INFO(log_msg);
        auto end = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double> during = end - start;
        max_during = std::max<double>(during.count(), max_during);
        std::cout << "线程：" << i << " 输出日志数：" << time << " 消耗时间：" << during.count() << "s\t"<< std::endl; }));
    }

    for (int k = 0; k < _threads.size(); k++)
        _threads[k].join();
    // 获取总消耗时间：多线程下，获取线程最大消耗时间：max(thr_size)
    std::cout << "总耗时: " << max_during << "s\t";
    // 获取每秒输出日志条数
    std::cout << "每秒输出日志条数: " << msg_num / max_during << std::endl;
    // 获取每秒输入大小(MB)
    std::cout << "每秒输入大小(MB): " << (msg_num * log_size) / (1024 * 1024) / max_during << "MB" << std::endl;
}

// 单
void _bench(size_t msg_num, size_t log_size)
{
    std::cout << " 单进程" << std::endl;
    double max_during = 0;
    std::string log_msg(log_size, 'c');
    auto start = std::chrono::high_resolution_clock::now();
    for (int n = 0; n < msg_num; n++)
        INFO(log_msg);
    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> during = end - start;
    max_during = std::max<double>(during.count(), max_during);
    std::cout << "线程：" << 0 << " 输出日志数：" << msg_num << " 消耗时间：" << during.count() << "s\t" << std::endl;

    std::cout << "每秒输出日志条数: " << msg_num / max_during << std::endl;
    // 获取每秒输入大小(KB)
    std::cout << "每秒输入大小(MB): " << (msg_num * log_size) / (1024 * 1024) / during.count() << "MB" << std::endl;
}

// 异步下
void Asyn()
{
    auto Z1 = log_p::SingletonBuilderLogger::GetInstance("Sayn-log", log_p::LoggerType::LOGGER_ASYN);
    std::string log("%m%n");
    Z1->builder_formater(log);
    Z1->builder_level(log_p::log_level::INFO);
    Z1->builder_sink_pool<log_p::RollFileBySizeSink>(1024 * 1024 * 3, "./log/log_by_size/log");
    Z1->build();
    std::cout << "日志模式：异步";
    thr_bench(4, 1000000, 60);
    // _bench(10000000, 60);
}

// 同步下
void Syn()
{
    auto Z1 = log_p::SingletonBuilderLogger::GetInstance("Ayn-log", log_p::LoggerType::LOGGER_SYN);
    std::string log("%m%n");
    Z1->builder_formater(log);
    Z1->builder_level(log_p::log_level::INFO);
    Z1->builder_sink_pool<log_p::RollFileBySizeSink>(1024 * 1024 * 3, "./log/log_by_size/log");
    Z1->build();
    std::cout << "日志模式：同步";
    // thr_bench(4, 10000000, 60);
    _bench(10000000, 60);
}

int main()
{
    Asyn();
    // Syn();
    return 0;
}
